home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / varia / silo.lha / silo / Sim.c < prev    next >
C/C++ Source or Header  |  1993-08-08  |  3KB  |  165 lines

  1. /* $Author: ecsv38 $ $Date: 90/08/21 14:45:59 $ $Revision: 1.1 $ */
  2. /* (c) S. Manoharan  sam@lfcs.edinburgh.ac.uk */
  3.  
  4. #include "Counter.h"
  5.  
  6. #include "Sim.h"
  7. #include "SimEventList.h"
  8.  
  9.  
  10. static Counter timer;
  11. static SimEventList eventlist;
  12.  
  13. Event *cause()
  14. {
  15.    if ( debug_level(1) ) {
  16.       cout << "\n---Begin{eventlist}\n";
  17.       ::eventlist.print();
  18.       cout << "\n---End{eventlist}\n";
  19.    }
  20.  
  21.  
  22.    Event *ev = ::eventlist.get();
  23.    if ( ev == 0 ) return 0;
  24.  
  25.    if ( ev->eventTime() > ::timer() ) 
  26.       ::timer.set(ev->eventTime());
  27.  
  28.    return ev;
  29. }
  30.  
  31. short cancel(const int eid)
  32. {
  33.    Event *ev = ::eventlist.remove(eid);
  34.  
  35.    if ( ev == 0 ) return 0;
  36.    else {
  37.       delete ev;
  38.       return 1;
  39.    }
  40. }
  41.  
  42. double simtime()
  43. {
  44.    return timer();
  45. }
  46.  
  47. Entity::Entity(char *const s)
  48. {
  49.    static int eid = 0;
  50.  
  51.    entity_name = s, entity_id = eid++;
  52. }
  53.  
  54. void
  55. Entity::schedule(const double delay, Event *const ev)
  56. {
  57.    if ( delay < 0 ) {
  58.       cout << form("%s: invalid delay %g\n", entity_name, delay);
  59.       exit(-1);
  60.    }
  61.    ev->scheduled_by(this);
  62.    ev->eventTime(::timer() + delay);
  63.  
  64.    ::eventlist.append(ev);
  65. }
  66.  
  67. short
  68. Resource::reserve(Entity *bywho, const int event_type)
  69. {
  70.    resource_used = 1;
  71.  
  72.    if ( bywho == 0 )
  73.       cout << form("** Error: reserve by null entity\n");
  74.  
  75.    bywho->currentEvent(event_type);
  76.    bywho->afterTime = 0;
  77.  
  78.    if ( available > 0 ) {
  79.       --available;
  80.       servedQ.append(bywho);
  81.       return 1;
  82.    }
  83.    else {
  84.       blockedQ.append(bywho);
  85.       return 0;
  86.    }
  87. }
  88.  
  89. short
  90. Resource::preempt(Entity *bywho, const int event_type)
  91. {
  92.    resource_used = 1;
  93.  
  94.    if ( bywho == 0 )
  95.       cout << form("** Error: preempt by null entity\n");
  96.  
  97.    bywho->currentEvent(event_type);
  98.    bywho->afterTime = 0;
  99.  
  100.    if ( available > 0 ) {
  101.       --available;
  102.       servedQ.append(bywho);
  103.       return 1;
  104.    }
  105.    else {
  106.       Entity *minPrioEnt = servedQ.remove(servedQ.min_entity_id());
  107.       if ( minPrioEnt->priority() >= bywho->priority() ) { // no preempt
  108.      blockedQ.append(bywho);
  109.      servedQ.append(minPrioEnt);
  110.      return 0;
  111.       }
  112.       else { // preempt
  113.      servedQ.append(bywho);
  114.      Event *stopped = ::eventlist.remove(minPrioEnt);
  115.      if ( stopped == 0 ) {
  116.         cout << form("** Error: no events for preempted entity\n");
  117.         return 0;
  118.      }
  119.      minPrioEnt->afterTime = stopped->eventTime() - simtime();
  120.      minPrioEnt->currentEvent(stopped->type());
  121.      blockedQ.insert(minPrioEnt);
  122.      delete stopped;
  123.          return 1;
  124.       }
  125.    }
  126. }
  127.  
  128. void
  129. Resource::release(Entity *const bywho)
  130. {
  131.    Entity *entity;
  132.  
  133.    if ( bywho == 0 )
  134.       cout << form("** Error: release by null entity\n");
  135.  
  136.    if ( debug_level(1) ) {
  137.       cout << form("Releasing resource %s\n", resource_name);
  138.       cout << "\n---Begin{blockedQ}\n";
  139.       blockedQ.print();
  140.       cout << "\n---End{blockedQ}\n";
  141.    }
  142.  
  143.    if ( servedQ.remove(bywho->id()) == 0 )
  144.       cout << form("** Error: release without reserve\n");
  145.  
  146.    if ( ( entity = blockedQ.get() ) != 0 ) {
  147.       Event *event = new Event(entity->currentEvent());
  148.       entity->schedule(entity->afterTime, event);
  149.       if ( entity->afterTime == 0 ) ++available;
  150.    }
  151.    else ++available;
  152. }
  153.  
  154. void
  155. Resource::set(const int sz)
  156. {
  157.    if ( resource_used ) {
  158.       cout << form("%s: resource already used. cannot set size\n",
  159.      resource_name);
  160.       exit(-1);
  161.    }
  162.    available = sz;
  163. }
  164.  
  165.